/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.orogeny.actions;

import com.softwarecraftsmen.orogeny.buildEnvironments.BuildEnvironment;
import com.softwarecraftsmen.orogeny.buildLogs.BuildLog;
import com.softwarecraftsmen.orogeny.actions.keys.ConvenientKey;
import com.softwarecraftsmen.orogeny.actions.keys.ConvenientKeyStore;
import com.softwarecraftsmen.orogeny.actions.zip.signing.JarSigner;
import com.softwarecraftsmen.orogeny.execution.SuccessOrFailure;
import static com.softwarecraftsmen.orogeny.execution.SuccessOrFailure.Success;
import static com.softwarecraftsmen.orogeny.execution.SuccessOrFailure.Failure;
import static com.softwarecraftsmen.orogeny.filing.AbsoluteDirectoriesAndFiles.absoluteDirectoriesAndFiles;
import com.softwarecraftsmen.orogeny.filing.AbsoluteFile;
import com.softwarecraftsmen.orogeny.filing.AbsolutePath;
import com.softwarecraftsmen.orogeny.filing.AbsolutePaths;
import static com.softwarecraftsmen.orogeny.filing.findFileFilters.AbstractFindFilesFilter.Jar;
import com.softwarecraftsmen.orogeny.filing.findFileFilters.FindFilesFilter;
import org.jetbrains.annotations.NotNull;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.concurrent.Callable;

public class SignJarsAction extends AbstractAction
{
	private final AbsolutePaths jarPath;
	private final FindFilesFilter findJars;
	private final ConvenientKey convenientKey;
	private final Callable<ConvenientKeyStore> callableConvenientKeyStore;

	public SignJarsAction(final @NotNull AbsolutePaths jarPath, final @NotNull ConvenientKey convenientKey, final @NotNull Callable<ConvenientKeyStore> callableConvenientKeyStore)
	{
		this.jarPath = jarPath;
		this.findJars = Jar;
		this.convenientKey = convenientKey;
		this.callableConvenientKeyStore = callableConvenientKeyStore;
	}

	@NotNull
	public String describeWhatWeDo()
	{
		return "signJars";
	}

	@NotNull
	public SuccessOrFailure execute(final @NotNull BuildLog buildLog, final @NotNull BuildEnvironment buildEnvironment)
	{
		final ConvenientKeyStore convenientKeyStore;
		try
		{
			convenientKeyStore = callableConvenientKeyStore.call();
		}
		catch (Exception e)
		{
			return Failure(e);
		}
		final PrivateKey privateKey = convenientKeyStore.getRsaPrivateKey(convenientKey);
		final X509Certificate[] signerCertificateChain = convenientKeyStore.getSignerCertificateChain(convenientKey);

		final JarSigner jarSigner = new JarSigner(buildLog, buildEnvironment);
		for (AbsoluteFile jarFile : jarPath.findFiles(findJars))
		{
			jarSigner.signJar(jarFile, convenientKey, privateKey, signerCertificateChain);
		}
		// TODO: Write out jar and move original!
		return Success;
	}

	@NotNull
	public static SpecifyJarPath signJars(final @NotNull AbsolutePath... jarPath)
	{
		return signJars(absoluteDirectoriesAndFiles(jarPath));
	}

	@NotNull
	public static SpecifyJarPath signJars(final @NotNull AbsolutePaths... jarPath)
	{
		return new SpecifyJarPath(absoluteDirectoriesAndFiles(jarPath));
	}

	public static final class SpecifyJarPath
	{
		private final AbsolutePaths jarPath;

		private SpecifyJarPath(final @NotNull AbsolutePaths jarPath) {this.jarPath = jarPath;}

		@NotNull
		public SpecifyKey using(final @NotNull ConvenientKey key)
		{
			return new SpecifyKey(key);
		}

		public final class SpecifyKey
		{
			private final ConvenientKey key;

			private SpecifyKey(final @NotNull ConvenientKey key) {this.key = key;}

			@NotNull
			public SignJarsAction in(final @NotNull Callable<ConvenientKeyStore> keyStore)
			{
				return new SignJarsAction(jarPath, key, keyStore);
			}
		}
	}
}
